import uuid
import math

from datetime import datetime
from django.db import models, transaction
from decimal import Decimal


from wxcloudrun.models import BaseModel

from warehouse.models import JuqiGood

from jqgame.raffle import weight_random


# Create your models here.


class WuxianshangArgs(BaseModel):
    # base info
    # 销售利润统计窗口，单位 day, 用于 统计窗口时间内 平台收入
    wxs_min_sale_profit_window = models.PositiveIntegerField(default=30)

    # 最低销售利润率 = 利润 / 销售总额
    # 无限赏整体利润利于此时，不再爆出 亏损奖品
    # 亏损奖品： 价值大于单次抽奖价值的奖品， 称为亏损奖品
    wxs_min_sale_profit_percent = models.DecimalField(
        default=Decimal("0.10"), max_digits=4, decimal_places=3
    )

    # 无限赏用户幸运值统计窗口，单位 day
    wxs_user_lucky_window = models.PositiveIntegerField(default=30)

    class Meta:
        db_table = "WuxianshangArgs"  # table name
        indexes = [
            models.Index(fields=["uuid"]),
            models.Index(fields=["deleted"]),
            models.Index(fields=["createdAt"]),
        ]


def get_wxs_args() -> WuxianshangArgs:
    if not WuxianshangArgs.objects.filter(id=1).exists():
        WuxianshangArgs().save()
    return WuxianshangArgs.objects.get(id=1)


class WuxianshangGame(BaseModel):
    record_update_time = True

    # base info
    # 0 is 待上架， 不可抽奖，可以修改关联商品
    # 1 is 上架， 可以抽奖，不可以修改关联商品
    state = models.IntegerField(default=0)

    name = models.CharField(max_length=100, unique=True)
    display_url = models.CharField(
        max_length=255,
    )
    price = models.PositiveIntegerField(default=999999)
    count = models.PositiveIntegerField(default=0)
    explain = models.UUIDField(null=True, verbose_name="说明uuid")
    ip_family = models.CharField(max_length=100, default="其他")
    score_pay = models.IntegerField(default=0, verbose_name="积分支付")
    baodi = models.IntegerField(default=0, verbose_name="保底模式")
    tianjiangsb = models.IntegerField(default=0, verbose_name="天降幸运")
    baodi_cp = models.IntegerField(default=0, verbose_name="保底值")
    tianjiang_num = models.IntegerField(default=0, verbose_name="天降幸运触发条件")
    is_fjf = models.IntegerField(default=0, verbose_name="返积分开启")
    is_hide = models.IntegerField(default=0, verbose_name="是否隐藏")
    feiqiu = models.IntegerField(default=0, verbose_name="非酋玩法")
    feiqiu_num = models.IntegerField(default=0, verbose_name="非酋触发值")
    # 拓展玩法
    extend_type_boss = models.BooleanField(default=False)

    class Meta:
        db_table = "WuxianshangGame"  # table name
        indexes = [
            models.Index(fields=["uuid"]),
            models.Index(fields=["deleted"]),
            models.Index(fields=["createdAt"]),
            models.Index(fields=["count"]),
            models.Index(fields=["name"]),
            models.Index(fields=["state"]),
            models.Index(fields=["ip_family"]),
        ]
        ordering = ["count", "-createdAt"]


class WuxianshangGameGood(BaseModel):
    record_update_time = True
    #
    game_uuid = models.UUIDField()
    good_uuid = models.UUIDField()
    good_weight = models.DecimalField(
        default=Decimal("0.50"), max_digits=7, decimal_places=2
    )
    level_uuid = models.UUIDField(null=True)
    good_type = models.IntegerField(
        default=0, verbose_name="赏品类型"
    )  # 0 随机抽取赏品 1保底赏品 2天降幸运产品 3非酋赏品
    cp = models.IntegerField(default=0, verbose_name="cp值")
    score = models.IntegerField(default=0, verbose_name="返还积分数值")
    good_rarity = models.CharField(max_length=100, default="未知")
    sort = models.IntegerField(default=1, verbose_name="赏品顺序")

    class Meta:
        db_table = "WuxianshangGameGood"  # table name
        indexes = [
            models.Index(fields=["uuid"]),
            models.Index(fields=["deleted"]),
            models.Index(fields=["createdAt"]),
            models.Index(fields=["game_uuid"]),
            models.Index(fields=["good_weight"]),
            models.Index(fields=["good_type"]),
            models.Index(fields=["good_uuid"]),
        ]
        ordering = ["good_weight", "good_uuid"]


class WuxianshangExtendBoss(BaseModel):
    # 当前 boss 赏属于 那个 无限赏
    game_uuid = models.UUIDField()
    name = models.CharField(max_length=100, unique=True)
    display_url = models.CharField(max_length=255)
    # 赏票 uuid 用来 查询 那些 用户, 拥有了当前 boss 赏的赏票
    # 门票会被创建为商品
    # 会被放入 用户背包，并且禁止出售， boss 赏开赏后，会自动兑换
    #   名称: boss赏票_盒子名称
    #   价格: （ 单轮 boss 赏所有商品价值 * 利润率） / 开奖数量
    #   图片：
    ticket_display_url = models.CharField(
        max_length=255,
    )

    # 赏票权重，决定赏票在无限赏的掉落概率
    ticket_weight = models.PositiveIntegerField()

    # 开奖数
    draw_num = models.PositiveIntegerField()

    # 赏票价格, 根据 boss 奖品计算
    ticket_uuid = models.UUIDField()
    ticket_price = models.PositiveIntegerField(default=999999)
    # 已发放赏票数量
    # 赏票数量 是 开奖数 整数倍时， 自动开奖
    ticket_count = models.PositiveIntegerField(default=0)

    # 开奖总数
    history_times = models.PositiveIntegerField(default=0)

    class Meta:
        db_table = "WuxianshangExtendBoss"  # table name
        indexes = [
            models.Index(fields=["uuid"]),
            models.Index(fields=["deleted"]),
            models.Index(fields=["createdAt"]),
            models.Index(fields=["game_uuid"]),
            models.Index(fields=["ticket_uuid"]),
        ]
        ordering = ["-createdAt"]


def create_boss_ticket(boss: WuxianshangExtendBoss):
    ticket_info = {
        "name": f"boss赏票_{boss.name}",
        "display_url": boss.ticket_display_url,
        "price": boss.ticket_price,
        "game_type": "无限赏",
        "ip_family": "赏票",
        "sale_able": False,
        "detail": "boss赏票不可出售, 开奖后自动兑换",
    }
    ticket = JuqiGood(**ticket_info)
    ticket.save()
    boss.ticket_uuid = ticket.uuid

    # add ticket to wuxianshang game good
    ticket_as_good = {
        "game_uuid": boss.game_uuid,
        "good_uuid": ticket.uuid,
        "good_weight": boss.ticket_weight,
    }
    WuxianshangGameGood(**ticket_as_good).save()


class WuxianshangExtendBossGood(BaseModel):
    # 无限赏 uuid
    game_uuid = models.UUIDField()
    # boos 赏 uuid
    extend_boss_uuid = models.UUIDField()

    # 商品 uuid
    good_uuid = models.UUIDField()
    count = models.PositiveIntegerField(default=0)
    is_global = models.BooleanField(default=True)
    good_rarity = models.CharField(max_length=100, default="未知")

    class Meta:
        db_table = "WuxianshangExtendBossGood"  # table name
        indexes = [
            models.Index(fields=["uuid"]),
            models.Index(fields=["deleted"]),
            models.Index(fields=["createdAt"]),
            models.Index(fields=["game_uuid"]),
            models.Index(fields=["extend_boss_uuid"]),
            models.Index(fields=["is_global"]),
        ]
        ordering = ["-createdAt"]


@transaction.atomic
def update_price_WuxianshangGame(game: WuxianshangGame):
    # only used by update_price_WuxianshangGame
    def _update_price_ExtendBoss(extendBoss: WuxianshangExtendBoss):
        boss_goods = WuxianshangExtendBossGood.objects.filter(
            game_uuid=extendBoss.game_uuid
        ).filter(deleted=False)
        ticket = JuqiGood.objects.get(uuid=extendBoss.ticket_uuid, deleted=False)

        all_value = 0

        for boss_good in boss_goods:
            count = boss_good.count
            good = JuqiGood.objects.get(uuid=boss_good.good_uuid, deleted=False)
            if boss_good.is_global:
                all_value += extendBoss.draw_num * good.price
            else:
                all_value += count * good.price

        profit = get_wxs_args().wxs_min_sale_profit_percent
        extendBoss.ticket_price = int(
            math.ceil((all_value * (1.0 + float(profit))) / extendBoss.draw_num / 100.0)
            * 100
        )
        ticket.price = extendBoss.ticket_price
        extendBoss.save()
        ticket.save()

    WuxianshangGame.objects.filter(uuid=game.uuid).select_for_update()
    WuxianshangGameGood.objects.select_for_update()
    WuxianshangExtendBossGood.objects.select_for_update()
    if game.extend_type_boss:
        extendBoss = (
            WuxianshangExtendBoss.objects.filter(game_uuid=game.uuid)
            .select_for_update()
            .first()
        )
        _update_price_ExtendBoss(extendBoss)

    game_goods = WuxianshangGameGood.objects.filter(game_uuid=game.uuid).filter(
        deleted=False
    )

    all_value = 0
    all_weight = 0
    for game_good in game_goods:
        weight = game_good.good_weight
        good = JuqiGood.objects.get(uuid=game_good.good_uuid, deleted=False)
        all_value += float(weight) * good.price
        all_weight += weight
    profit = get_wxs_args().wxs_min_sale_profit_percent
    game.price = int(
        math.ceil((all_value * (1.0 + float(profit))) / float(all_weight) / 100.0) * 100
    )
    game.save()


class WuxianshangRaffleRecord(BaseModel):
    #
    user_uuid = models.UUIDField()
    game_uuid = models.UUIDField()
    good_uuid = models.UUIDField()
    count = models.PositiveIntegerField()
    raffle_count = models.PositiveIntegerField(default=0)

    extend_type_boss = models.BooleanField(default=False)
    boss_history_times = models.PositiveIntegerField(default=0)

    class Meta:
        db_table = "WuxianshangRaffleRecord"  # table name
        indexes = [
            models.Index(fields=["uuid"]),
            models.Index(fields=["deleted"]),
            models.Index(fields=["createdAt"]),
            models.Index(fields=["user_uuid"]),
            models.Index(fields=["good_uuid"]),
            models.Index(fields=["game_uuid"]),
            models.Index(fields=["raffle_count"]),
        ]
        ordering = ["-id"]


def wxs_raffle(game: WuxianshangGame, count: int):
    game_goods = (
        WuxianshangGameGood.objects.filter(game_uuid=game.uuid)
        .filter(deleted=False)
        .select_for_update()
        .all()
    )
    m = {}
    for game_good in game_goods:
        m[game_good.good_uuid] = game_good.good_weight

    raffle_goods = {}
    for _ in range(count):
        good_uuid = weight_random(m)
        if raffle_goods.get(good_uuid, None):
            raffle_goods[good_uuid] += 1
        else:
            raffle_goods[good_uuid] = 1

    return raffle_goods


class TianjiangGoods(BaseModel):
    user_uuid = models.UUIDField()
    game_uuid = models.UUIDField()
    good_uuid = models.UUIDField()
    count = models.PositiveIntegerField(default=0, verbose_name="第几发出的")
    start_count = models.PositiveBigIntegerField(default=0, verbose_name="起始抽奖号")
    end_count = models.PositiveBigIntegerField(default=0, verbose_name="结束抽奖")

    class Meta:
        db_table = "TianjiangGoods"
        indexes = [
            models.Index(fields=["uuid"]),
            models.Index(fields=["deleted"]),
            models.Index(fields=["createdAt"]),
            models.Index(fields=["user_uuid"]),
            models.Index(fields=["game_uuid"]),
        ]
        ordering = ["-id"]


class FeiqiuRecord(BaseModel):
    user_uuid = models.UUIDField()
    game_uuid = models.UUIDField()
    good_uuid = models.UUIDField()
    start_count = models.PositiveBigIntegerField(default=0, verbose_name="起始抽奖号")
    end_count = models.PositiveBigIntegerField(default=0, verbose_name="结束抽奖")

    class Meta:
        db_table = "FeiqiuRecord"
        indexes = [
            models.Index(fields=["uuid"]),
            models.Index(fields=["deleted"]),
            models.Index(fields=["createdAt"]),
            models.Index(fields=["user_uuid"]),
            models.Index(fields=["game_uuid"]),
        ]
        ordering = ["-id"]
